#ifndef _PSAPI_DYNLINK_H_
#define _PSAPI_DYNLINK_H_

#include <psapi.h>

// Try to load the psapi.dll 
// returns 
//     0 if library was not found, 
//     1 if all symbols were loaded and 
//     2 if some symbols are NULL 
int psapi_load();

typedef BOOL
(WINAPI *
EnumProcesses_t)(
    __out_bcount(cb) DWORD * lpidProcess,
    __in DWORD cb,
    __out LPDWORD lpcbNeeded
    );

typedef BOOL
(WINAPI *
EnumProcessModules_t)(
    __in  HANDLE hProcess,
    __out_bcount(cb) HMODULE *lphModule,
    __in  DWORD cb,
    __out LPDWORD lpcbNeeded
    );

typedef BOOL
(WINAPI *
EnumProcessModulesEx_t)(
    __in  HANDLE hProcess,
    __out_bcount(cb)  HMODULE *lphModule,
    __in  DWORD cb,
    __out  LPDWORD lpcbNeeded,
    __in  DWORD dwFilterFlag
    );

typedef DWORD
(WINAPI *
GetModuleBaseNameA_t)(
    __in HANDLE hProcess,
    __in_opt HMODULE hModule,
    __out_ecount(nSize) LPSTR lpBaseName,
    __in DWORD nSize
    );

typedef DWORD
(WINAPI *
GetModuleBaseNameW_t)(
    __in HANDLE hProcess,
    __in_opt HMODULE hModule,
    __out_ecount(nSize) LPWSTR lpBaseName,
    __in DWORD nSize
    );

typedef DWORD
(WINAPI *
GetModuleFileNameExA_t)(
    __in HANDLE hProcess,
    __in_opt HMODULE hModule,
    __out_ecount(nSize) LPSTR lpFilename,
    __in DWORD nSize
    );

typedef DWORD
(WINAPI *
GetModuleFileNameExW_t)(
    __in HANDLE hProcess,
    __in_opt HMODULE hModule,
    __out_ecount(nSize) LPWSTR lpFilename,
    __in DWORD nSize
    );

typedef BOOL
(WINAPI *
GetModuleInformation_t)(
    __in HANDLE hProcess,
    __in HMODULE hModule,
    __out LPMODULEINFO lpmodinfo,
    __in DWORD cb
    );


typedef BOOL
(WINAPI *
EmptyWorkingSet_t)(
    __in HANDLE hProcess
    );


typedef BOOL
(WINAPI *
GetWsChanges_t)(
    __in HANDLE hProcess,
    __out_bcount(cb) PPSAPI_WS_WATCH_INFORMATION lpWatchInfo,
    __in DWORD cb
    );

typedef BOOL
(WINAPI *
GetWsChangesEx_t)(
    __in HANDLE hProcess,
    __out_bcount_part(*cb, *cb) PPSAPI_WS_WATCH_INFORMATION_EX lpWatchInfoEx,
    __inout PDWORD cb
    );

typedef DWORD
(WINAPI *
GetMappedFileNameW_t)(
    __in HANDLE hProcess,
    __in LPVOID lpv,
    __out_ecount(nSize) LPWSTR lpFilename,
    __in DWORD nSize
    );

typedef DWORD
(WINAPI *
GetMappedFileNameA_t)(
    __in HANDLE hProcess,
    __in LPVOID lpv,
    __out_ecount(nSize) LPSTR lpFilename,
    __in DWORD nSize
    );


typedef BOOL
(WINAPI *
EnumDeviceDrivers_t)(
    __out_bcount(cb) LPVOID *lpImageBase,
    __in DWORD cb,
    __out LPDWORD lpcbNeeded
    );


typedef DWORD
(WINAPI *
GetDeviceDriverBaseNameA_t)(
    __in LPVOID ImageBase,
    __out_ecount(nSize) LPSTR lpFilename,
    __in DWORD nSize
    );

typedef DWORD
(WINAPI *
GetDeviceDriverBaseNameW_t)(
    __in LPVOID ImageBase,
    __out_ecount(nSize) LPWSTR lpBaseName,
    __in DWORD nSize
    );


typedef DWORD
(WINAPI *
GetDeviceDriverFileNameA_t)(
    __in LPVOID ImageBase,
    __out_ecount(nSize) LPSTR lpFilename,
    __in DWORD nSize
    );

typedef DWORD
(WINAPI *
GetDeviceDriverFileNameW_t)(
    __in LPVOID ImageBase,
    __out_ecount(nSize) LPWSTR lpFilename,
    __in DWORD nSize
    );


typedef BOOL
(WINAPI *
GetProcessMemoryInfo_t)(
    HANDLE Process,
    PPROCESS_MEMORY_COUNTERS ppsmemCounters,
    DWORD cb
    );


typedef BOOL
(WINAPI *
GetPerformanceInfo_t)(
    PPERFORMANCE_INFORMATION pPerformanceInformation,
    DWORD cb
    );

typedef BOOL
(WINAPI *
EnumPageFilesW_t)(
    PENUM_PAGE_FILE_CALLBACKW pCallBackRoutine,
    LPVOID pContext
    );

typedef BOOL
(WINAPI *
EnumPageFilesA_t)(
    PENUM_PAGE_FILE_CALLBACKA pCallBackRoutine,
    LPVOID pContext
    );

typedef DWORD
(WINAPI *
GetProcessImageFileNameA_t)(
    __in HANDLE hProcess,
    __out_ecount(nSize) LPSTR lpImageFileName,
    __in DWORD nSize
    );

typedef DWORD
(WINAPI *
GetProcessImageFileNameW_t)(
    __in HANDLE hProcess,
    __out_ecount(nSize) LPWSTR lpImageFileName,
    __in DWORD nSize
    );


extern EnumProcesses_t pEnumProcesses;
extern EnumProcessModules_t pEnumProcessModules;
extern EnumProcessModulesEx_t pEnumProcessModulesEx;
extern GetModuleBaseNameA_t pGetModuleBaseNameA;
extern GetModuleBaseNameW_t pGetModuleBaseNameW;
extern GetModuleFileNameExA_t pGetModuleFileNameExA;
extern GetModuleFileNameExW_t pGetModuleFileNameExW;
extern GetModuleInformation_t pGetModuleInformation;
extern EmptyWorkingSet_t pEmptyWorkingSet;
extern GetWsChanges_t pGetWsChanges;
extern GetWsChangesEx_t pGetWsChangesEx;
extern GetMappedFileNameW_t pGetMappedFileNameW;
extern GetMappedFileNameA_t pGetMappedFileNameA;
extern EnumDeviceDrivers_t pEnumDeviceDrivers;
extern GetDeviceDriverBaseNameA_t pGetDeviceDriverBaseNameA;
extern GetDeviceDriverBaseNameW_t pGetDeviceDriverBaseNameW;
extern GetDeviceDriverFileNameA_t pGetDeviceDriverFileNameA;
extern GetDeviceDriverFileNameW_t pGetDeviceDriverFileNameW;
extern GetProcessMemoryInfo_t pGetProcessMemoryInfo;
extern GetPerformanceInfo_t pGetPerformanceInfo;
extern EnumPageFilesW_t pEnumPageFilesW;
extern EnumPageFilesA_t pEnumPageFilesA;
extern GetProcessImageFileNameA_t pGetProcessImageFileNameA;
extern GetProcessImageFileNameW_t pGetProcessImageFileNameW;

#endif

